package com.example.aqs;

import lombok.SneakyThrows;

import java.util.concurrent.CountDownLatch;
/**
 * create by mwh 2021-12-21
 **/

public class CountDown {

    private static int LATCH_SIZE = 5;
    private static CountDownLatch doneSignal;
//        public static void main(String[] args) throws Exception {
//
//                doneSignal = new CountDownLatch(LATCH_SIZE);
//
//                // 新建5个任务
//                for(int i=0; i<LATCH_SIZE; i++)
//                    new InnerThread().start();
//
//                System.out.println("main await begin.");
//                // "主线程"等待线程池中5个任务的完成
//                doneSignal.await();
//
//                System.out.println("main await finished.");
//        }
//
//        static class InnerThread extends Thread{
//            public void run() {
//                    System.out.println(Thread.currentThread().getName() + " sleep 1000ms.");
//                    // 将CountDownLatch的数值减1
//                    doneSignal.countDown();
//            }
//        }
//}

    /**
     * 输出应该是：
     * thread 1 sleep--更下面这个竞争线程关系，并发，排序可能颠倒
     * main wait begin---更上面这个竞争线程关系，并发，排序可能颠倒
     * thread2 sleep--后面从thread2 ~thread5随机前后关系，因为上步走完，走donesignal.await，将main线程挂起，等待coutdown的全部走完，也就是countdown从5到0
     * thread 4 sleep
     * thread 3 sleep
     * thred 5 sleep
     * main aweit finish
     */


//一个更加明显的例子，考试问题，两个学生，两个学生都交卷才算考试结束

    /**
     * 如果没有1234步返回：
     * ====开始考试--第一个和第二个都是顺序随机
     * main===考试完毕
     * Thread-0第一个学生交卷
     * Thread-1第二个学生交卷
     *
     *
     * 加上后：
     *====开始考试
     * Thread-0第一个学生交卷
     * Thread-1第二个学生交卷
     * main===考试完毕s
     *
     */
    public static void main(String[] args) throws Exception {
//---------1
      doneSignal = new CountDownLatch(2);

        System.out.println("====开始考试");
        //---------2

//第一个学生参加考试
        new Thread(
                new Runnable() {
                    @SneakyThrows
                    @Override
                    public void run() {
                        System.out.println(Thread.currentThread().getName() + "第一个学生交卷");
                        Thread.sleep(1000);
                        //--------------3
                        doneSignal.countDown();
                    }
                }
        ).start();
//第二个学生参加考试
        new Thread(
                new Runnable() {
                    @SneakyThrows
                    @Override
                    public void run() {
                        System.out.println(Thread.currentThread().getName() + "第二个学生交卷");
                        Thread.sleep(1000);
                        //--------------4
                        doneSignal.countDown();
                    }
                }
        ).start();
        //------5
        //这个await在哪里出现，就哪里等doneSignal=0
        doneSignal.await();
        System.out.println(Thread.currentThread().getName()+"===考试完毕");

    }
}

